using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;

public enum SocketType
{
    LOGIN,
    BATTLE,
    HERO,
    CHAT,
    MAIL,
}


public class NetMsg
{
    public int msgId;
    public int sid;
    public int result;
    public ByteBuffer msg;

    public NetMsg(int msgId, int sid, int result, ByteBuffer msg)
    {
        this.msgId = msgId;
        this.sid = sid;
        this.msg = msg;
        this.result = result;
    }
}
public class NetworkStateInfo
{
    public NetworkStateType type;
    public string msg;
}
public class NetworkManager : UnitySingleton<NetworkManager>
{
    private List<SocketClient> socketList = new List<SocketClient>();
    private Dictionary<SocketType,SocketClient> socketDic = new Dictionary<SocketType,SocketClient>();

    void OnApplicationQuit()
    {
        Reset();
    }

    void OnDestroy()
    {
        Reset();
    }

    public void Reset()
    {
        foreach (var s in socketList)
        {
            s.Close();
        }
        socketList.Clear();
    }

    void Update()
    {
        for (int i = 0; i < socketList.Count; i++)
        {
            socketList[i].Update();
        }
    }

    public SocketClient AddSocket(SocketType socketType, string ipAddress, int port)
    {
        SocketClient socket = new SocketClient(ipAddress, port);
        socket.netMgr = this;
        socketList.Add(socket);
        socketDic[socketType] = socket;
        return socket;
    }
    
    public SocketClient GetSocket(SocketType socketType)
    {
        return socketDic[socketType];
    }

    public void SendGetHttp(string url, Action<string> callback, Action errorAction = null)
    {
        Debug.LogWarning("http:" + url);    
        StartCoroutine(HttpGet_Co(url, callback, errorAction));
        Debug.LogWarning("http22222:"); 
    }

    IEnumerator HttpGet_Co(string url, Action<string> callback, Action errorAction)
    {
        Debug.LogWarning("HttpGet_Co:" + url);
        if (string.IsNullOrEmpty(url))
        {
            errorAction?.Invoke();
            yield break;
        }

        UnityWebRequest request = UnityWebRequest.Get(url);
        request.certificateHandler = new AcceptAllCertificatesHandler();
        Debug.LogError("HttpGet url::" + url);
        yield return request.SendWebRequest();

        if (request.isNetworkError)
        {
            Debug.LogError("url::" + url + " HttpGet Error: " + request.error);
            errorAction?.Invoke();
        }
        else
        {
            var result = request.downloadHandler.text;
            Debug.LogError(" HttpGet result: " + result);
            callback?.Invoke(result);
        }
    }

    public void SendPostRequest(string url, string jsonData, Action<string> callback, Action errorAction = null)
    {
        StartCoroutine(HttpPost_Co(url, jsonData, callback, errorAction));
    }

    IEnumerator HttpPost_Co(string url, string jsonData, Action<string> callback, Action errorAction)
    {
        if (string.IsNullOrEmpty(url))
        {
            errorAction?.Invoke();
            yield break;
        }

        using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
        {
            byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            request.certificateHandler = new AcceptAllCertificatesHandler();

            yield return request.SendWebRequest();

            if (request.isNetworkError)
            {
                Debug.LogError("HttpPostError: " + request.error);
                errorAction?.Invoke();
            }
            else
            {
                callback?.Invoke(request.downloadHandler.text);
            }
        }
    }

    public void ReceiveErrorInfo(byte[] msg)
    {
        NetManager.ReceiveErrorInfo(msg);
    }
}

public class AcceptAllCertificatesHandler : CertificateHandler
{
    protected override bool ValidateCertificate(byte[] certificateData)
    {
        return true;
    }
}